﻿using System;
using Gadgeteer.Interfaces;
using Microsoft.SPOT;

using GT = Gadgeteer;
using GTM = Gadgeteer.Modules;
using GTI = Gadgeteer.Interfaces;

namespace Gadgeteer.Modules.Sytech
{
    /// <summary>
    /// A Serial2USB Gadgeteer module
    /// </summary>
    /// 
    ///     /// <example>
    /// <para>The following example show intialization of a <see cref="SerialCamera"/> object </para>
    /// <code>
    /// using System;
    /// using Microsoft.SPOT;
    /// using Microsoft.SPOT.Presentation;
    /// using Microsoft.SPOT.Presentation.Controls;
    /// using Microsoft.SPOT.Presentation.Media;
    ///
    /// using GT = Gadgeteer;
    /// using GTM = Gadgeteer.Modules;
    ///
    /// using Gadgeteer.Modules.Sytech;
    ///
    /// namespace GadgeteerAppGettingStarted
    /// {
    ///     public partial class Program
    ///     {
    ///         // This template uses the NANAO mainboard from Sytech Designs
    ///
    ///         // Define and initialize GTM.Modules here, specifying their socket numbers.   
    ///         // Needs a USB Device module for connection to VS and suppying power     
    ///         GTM.Sytech.UsbDevice usbClient = new UsbDevice(1);
    ///         GTM.Sytech.Button button = new Button(2);
    ///
    ///          
    ///            
    ///         
    ///         
    /// 
    ///         GTM.Sytech.Serial2USB serial2USB = new Serial2USB(2);
    ///
    ///         void ProgramStarted()
    ///         {
    ///             // Initialize event handlers here.
    ///             
    ///              button.ButtonPressed += new Button.ButtonEventHandler(button_ButtonPressed);
    ///             // Do one-time tasks here
    ///            
    /// 
    ///             
    ///             Debug.Print("Program Started");
    ///         }
    ///
    ///         void button_ButtonPressed(Button sender, Button.ButtonState state)
    ///         {
    ///             serial2USB.GetPort.Write("Button Pushed - serial string");
    ///         }
    /// 
    ///         
    ///         //Event handler for progress event
    ///         //Just show data on debug output
    ///        void SerialCamera_OnPictureProgess(object sender, ProgressEventArg arg)
    ///        {
    ///            Debug.Print("Picture progress size : " + arg.size + " blocks:" + arg.Blocks + " this block:" + arg.blockReceived);
    ///        }
    /// 
    ///         
    ///     }
    /// }
    ///
    /// </code>
    /// </example>
    public class Serial2USB : GTM.Module
    {
        

        private Gadgeteer.Interfaces.Serial m_serial;
        private Socket socket;

        // Note: A constructor summary is auto-generated by the doc builder.
        /// <summary></summary>
        /// <param name="socketNumber">The socket that this module is plugged in to.</param>
        public Serial2USB(int socketNumber)
        {
            // This finds the Socket instance from the user-specified socket number.  
            // This will generate user-friendly error messages if the socket is invalid.
            // If there is more than one socket on this module, then instead of "null" for the last parameter, 
            // put text that identifies the socket to the user (e.g. "S" if there is a socket type S)
            socket = Socket.GetSocket(socketNumber, true, this, null);


            //Validate Socket choice
            socket.EnsureTypeIsSupported(new char[] {'K','U'}, this);

        //    m_serial = new Serial(socket,38400,Serial.SerialParity.None,Serial.SerialStopBits.One,8,Serial.HardwareFlowControl.NotRequired,this);
        
        }

        /// <summary>
        /// Returns the Gadgeteer <see cref="Gadgeteer.Interfaces.Serial"/> interface for this module.
        /// If one has not been created (by calling configure, or a previous call to
        /// this method) then one is created with default settings of
        /// 38800 baud, 8 data, 1 stop but and no parity or handshake.
        /// 
        /// If you dont want the default settings then call configure <see cref="Configure"/> first
        /// 
        /// 
        /// </summary>
        public Serial GetPort
        {
            get
            {
                if ( m_serial == null)
                {
                    // configure serial interface with default values
                    Configure(38400,Serial.SerialParity.None,Serial.SerialStopBits.One,8,false);
                }
                return m_serial;
            }
        }

        /// <summary>
        /// Configure the serial interface for this module.
        /// This can only be done once
        /// This must be done before calling <see cref="GetPort"/> other wise
        /// GetPort will set up default settings
        /// </summary>
        /// <param name="baudrate">the baud rate</param>
        /// <param name="parity">Gadgeteer Serial Parity enumeration</param>
        /// <param name="stopBits">Gadgeteer Serial stop bits enum</param>
        /// <param name="dataBits">number of data bits</param>
        /// <param name="useHandshakeIfAvail">true if handshake to be used if supported</param>
        public void Configure(int baudrate, GTI.Serial.SerialParity parity, 
                              GTI.Serial.SerialStopBits stopBits,
                              int dataBits, bool useHandshakeIfAvail)
        {
            if ( m_serial != null)
            {
                throw new Exception("Serial2USB.Configure can only be called once");
                //modify to dispose of old port and create a new one
            }

            Serial.HardwareFlowControl flowControl = Serial.HardwareFlowControl.NotRequired;
            if ( useHandshakeIfAvail)
            {
                flowControl = Serial.HardwareFlowControl.UseIfAvailable;
            }

            m_serial = new Serial(socket, baudrate, parity, stopBits, dataBits, flowControl, this);

        }
            
       

        

        
  
       

        
    }
}
